package org.huatek.anders.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.huatek.anders.constants.RedisKeys;
import org.huatek.anders.entity.OpenUserEntity;
import org.huatek.anders.utils.R;
import org.huatek.anders.utils.RedisUtils;
import org.huatek.anders.utils.jwt.JwtCheck;
import org.huatek.anders.utils.jwt.JwtResponse;
import org.huatek.anders.utils.jwt.JwtSubject;
import org.huatek.anders.utils.jwt.JwtToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;

/**
 * @author anders
 * @date 2018-12-04 12:48
 **/
@Slf4j
@Component
public class TokenInterceptor implements HandlerInterceptor {

    private final RedisUtils redisUtils;

    @Autowired
    public TokenInterceptor(RedisUtils redisUtils) {
        this.redisUtils = redisUtils;
    }

    @Value("${common.visitor.url}")
    private String[] visitorUrl;
    @Value("${common.token.name}")
    private String tokenName;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String visitUrl = request.getRequestURL().toString();
        String token = JwtToken.getToken(request, tokenName);
        if (Arrays.stream(visitorUrl).anyMatch(url -> visitUrl.indexOf(url) > 0)) {
            log.debug("url 不拦截：" + visitUrl);
            return true;
        } else {
            ObjectMapper mapper = new ObjectMapper();
            JwtCheck jwtCheck = JwtToken.checkToken(token);
            if (jwtCheck.getCode() > 0) {
                JwtSubject jwtSubject = mapper.readValue(jwtCheck.getSubject(), JwtSubject.class);
                if (!StringUtils.isEmpty(jwtSubject)) {
                    String userId = jwtSubject.getUserId();
///                    String redisToken = redisUtils.get(RedisKeys.OAUTH2_USER_TOKEN + userId);
//                    if (!token.equals(redisToken)){
//                        //已退出登陆，redis原token已删除
//                        JwtResponse.toJson(response, R.error("token 已失效，请重新登陆"));
//                        return false;
//                    }
                    OpenUserEntity openUserEntity = redisUtils.get(RedisKeys.OAUTH2_USER + userId, OpenUserEntity.class);
                    //登陆来源类型
                    openUserEntity.setType(jwtSubject.getType());
                    //放入request处理业务
                    request.setAttribute("loginUser", openUserEntity);
                    return true;
                } else {
                    JwtResponse.toJson(response, R.error("token 认证失败"));
                    return false;
                }
            } else {
                switch (jwtCheck.getCode()) {
                    case -1:
                        JwtResponse.toJson(response, R.error("token 认证失败"));
                        break;
                    case -2:
                        JwtResponse.toJson(response, R.error("token 过期"));
                        break;
                    default:
                        break;
                }
                return false;
            }
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {

    }
}
